from fastapi import FastAPI, APIRouter, status, Request, HTTPException, Depends
from fastapi.responses import JSONResponse
from fastapi.exceptions import RequestValidationError
from fastapi.middleware.cors import CORSMiddleware
from starlette.exceptions import HTTPException as StarletteHTTPException
from typing import Optional
from core import Logger, Config
from core.models.api import APICode, APIResult

from core.context import Context

from core.apis import api_router

root_router = APIRouter()

def verify_token(request: Request):
    path: str = request.get('path')
    if path.startswith('/v1/user') or path.startswith("/v1/healthcheck"):
        pass
    else:
        token = request.headers.get('Authorization')  
        if not token or token not in Config.get_tokens():  # validate_token是假设存在的验证函数  
            raise HTTPException(status_code=status.HTTP_403_FORBIDDEN, detail="Invalid token")
        
def create_app(ctx: Optional[Context]=Context()) -> FastAPI:
    app = FastAPI(
        title="distdl",
        version="0.0.1",
        dependencies=[Depends(verify_token)]
    )
    app.state.ctx = ctx
    app.add_middleware(
        CORSMiddleware,
        allow_origins=['*'],
        allow_credentials=True,
        allow_methods=['*'],
        allow_headers=['*'],
    )
    root_router.include_router(api_router)
    app.include_router(root_router)

    @app.exception_handler(StarletteHTTPException)
    async def custom_http_exception_handler(request, exc :StarletteHTTPException):
        return JSONResponse(
            status_code=exc.status_code,
            content=APIResult(code=APICode.Failed, msg=str(exc.detail)).dict(exclude_none=True, exclude_unset=True)
        )
    #{"detail": exc.errors(), "body": exc.body}
    @app.exception_handler(RequestValidationError)
    async def validation_exception_handler(request: Request, exc: RequestValidationError):
        return JSONResponse(
            status_code=status.HTTP_422_UNPROCESSABLE_ENTITY,
            content=APIResult(code=APICode.Failed, 
                              msg=str("参数验证错误"),
                              data={"detail": exc.errors(), "body": exc.body}
                              ).dict(exclude_none=True, exclude_unset=True)
        )
    
    return app



@api_router.get("/healthcheck", status_code=status.HTTP_200_OK, response_model=APIResult)
def health_check():
    """
    执行健康检查的函数，用于确认系统或服务是否处于正常运行状态。

    参数:
    无

    返回值:
    APIResult: 包含代码和消息的对象。代码为0表示成功，消息为"ok"。
    """
    return APIResult(code=0, msg="ok")

